﻿/*
 * This software is the confidential and proprietary
 * information of NetBay
 * Such confidential information should not be disclosed
 * NetBay copyright(c) 2010
 */

#region Using
using System;
using System.Reflection;
using System.Resources;
using System.Globalization;
using System.Threading;
using NetBay.Core.Log;
#endregion

namespace NetBay.Core.Globalization
{
    /// <summary>
    /// Used to localize .NET assembly
    /// </summary>
    public class GlobalizationManager
    {
        #region Private members
        private string m_sResourceNamespace = string.Empty;
        private Assembly m_oReferenceAssembly;
        private ResourceManager m_oResourceManager;
        private CultureInfo m_oCurrentCultureInfo = Thread.CurrentThread.CurrentCulture;
        #endregion

        #region Properties
        /// <summary>
        /// Gets or sets the namespace of the localized assembly dictionnary.
        /// </summary>
        /// <value>The namespace of the localized assembly dictionnary.</value>
        public string ResourceNamespace
        {
            get { return m_sResourceNamespace; }
            set
            {
                m_sResourceNamespace = value;
                UpdateResourceManager();
            }
        }

        /// <summary>
        /// Gets or sets the reference assembly to localize.
        /// </summary>
        /// <value>The reference assembly to localize.</value>
        public Assembly ReferenceAssembly
        {
            set { m_oReferenceAssembly = value; }
        }

        /// <summary>
        /// Gets or sets the culture used for the localization process.
        /// </summary>
        /// <value>The culture info used for the localization process.</value>
        public CultureInfo CurrentCultureInfo
        {
            get { return m_oCurrentCultureInfo; }
            set { this.m_oCurrentCultureInfo = value; }
        }

        /// <summary>
        /// Gets the internal resource manager.
        /// </summary>
        /// <value>The internal resource manager.</value>
        public ResourceManager InternalResourceManager
        {
            get { return m_oResourceManager; }
        }

        #endregion

        #region Methods
        /// <summary>
        /// Updates the resource manager.
        /// </summary>
        internal void UpdateResourceManager()
        {
            this.m_oResourceManager = new ResourceManager(m_sResourceNamespace, m_oReferenceAssembly);
        }

        /// <summary>
        /// Gets the string.
        /// </summary>
        /// <param name="p_sKey">The key.</param>
        /// <returns></returns>
        public string GetString(string p_sKey)
        {
            return GetString(p_sKey, this.CurrentCultureInfo);
        }

        /// <summary>
        /// Gets the localized string associated to the dictionnary key following the specified culture.
        /// </summary>
        /// <param name="p_sKey">The key of the string.</param>
        /// <returns>The localized string associated to the key</returns>
        public string GetString(string p_sKey, CultureInfo p_oCultureInfo)
        {
            if (string.IsNullOrEmpty(p_sKey))
                return null;
            try
            {
                return m_oResourceManager.GetString(p_sKey, p_oCultureInfo);
            }
            catch (NullReferenceException nullReferenceException)
            {
                LogManager.Instance().LogErrorFormat(
                    nullReferenceException,
                            "Cannot translate the key '{0}' in {1} ({2})",
                            p_sKey,
                            this.m_oCurrentCultureInfo.DisplayName,
                            "Bad initialization !");
                throw new GlobalizationException("Cannot retrieve the specified string. First set the resource namespace!");
            }
            catch (MissingManifestResourceException missingManifestResourceException)
            {
                LogManager.Instance().LogErrorFormat(
                    missingManifestResourceException,
                            "Cannot translate the key '{0}' in {1} ({2})",
                            p_sKey,
                            this.m_oCurrentCultureInfo.DisplayName,
                            missingManifestResourceException);
                return null;
            }
        }

        /// <summary>
        /// Gets the localized object associated to the dictionnary key following the specified culture.
        /// </summary>
        /// <param name="p_sKey">The key of the object.</param>
        /// <returns>The localized object associated to the key</returns>
        public object GetObject(string p_sKey)
        {
            if (string.IsNullOrEmpty(p_sKey))
                return null;
            try
            {
                return m_oResourceManager.GetObject(p_sKey, this.m_oCurrentCultureInfo);
            }
            catch (NullReferenceException nullReferenceException)
            {
                LogManager.Instance().LogErrorFormat(
                    nullReferenceException,
                            "Cannot get the object from the key '{0}' in {1} ({2})",
                            p_sKey,
                            this.m_oCurrentCultureInfo.DisplayName,
                            "Bad initialization !");
                throw new GlobalizationException("Cannot retrieve the specified object. First set the resource namespace!");
            }
            catch (MissingManifestResourceException missingManifestResourceException)
            {
                LogManager.Instance().LogErrorFormat(
                    missingManifestResourceException,
                            "Cannot get the object from the key '{0}' in {1} ({2})",
                            p_sKey,
                            this.m_oCurrentCultureInfo.DisplayName,
                            missingManifestResourceException);
                return null;
            }
        }

        /// <summary>
        /// Gets the resource set.
        /// </summary>
        /// <returns></returns>
        internal ResourceSet GetResourceSet()
        {
            return m_oResourceManager.GetResourceSet(this.m_oCurrentCultureInfo, true, false);
        }

        #endregion
    }
}
